/*********************************************************************************
 *
 *
 *
 **********************************************************************************/
package util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;

import base.Global.NetType;
/**
 *@name EdgeDeweigh.java
 *@description 
 *@author 王进法<Mervin.Wong>
 *@version 
 *@Date 2013-1-16上午10:36:55
 */
/*********************************************************************************
 *
 * 说明：
 * 	1，功能：对于网络拓扑中的边去重，
 * 			例如：（1），边的两个端点相同；
 * 				 （2），该条边已存在网络中，
 * 				 （3），如果时无向网络，还要删除[A-B][B-A]其中一条
 * 2，操作步骤：
 * 3，运行示例：	EdgeDeweigh ed = new EdgeDeweigh("../data/ips.txt","../data/edge2.txt");
				Edge.netType = ed.netType;
				ed.reduce();
 **********************************************************************************/

public class EdgeDeweigh {
	private String fileName = null;//要操作的文件
	private String savePath = null;//将结果保存的文件路径
	private NetType netType = null;//有向还是无向网络
	public HashSet<Edge> edgeSet = null;
	
	public  EdgeDeweigh(String fileName, String savePath){
		this.fileName = fileName;
		this.savePath = savePath;
		this.netType = NetType.INDIRECTED_NET;//无向
		Edge.netType = this.netType;
	}

	public  EdgeDeweigh(String fileName, String savePath, NetType netType){
		this.fileName = fileName;
		this.savePath = savePath;
		this.netType = netType;
		Edge.netType = this.netType;
	}
	
	public void reduce(){
		try {
			BufferedReader reader = new BufferedReader(new FileReader(this.fileName));
			BufferedWriter writer = new BufferedWriter(new FileWriter(this.savePath));
			String line = null;
			String[] lineArr = null;
			edgeSet = new HashSet<Edge>();
			//Edge edge = null;
			long pre, post;
			while((line = reader.readLine()) != null){
				lineArr = line.split("\\t");
				pre = Long.parseLong(lineArr[0]);
				post = Long.parseLong(lineArr[1]);
				D.p(lineArr[0]+"###"+lineArr[1]);
				if(this.netType == NetType.INDIRECTED_NET){
					if(pre < post){
						edgeSet.add(new Edge(pre, post));
					}else if(pre > post){
						edgeSet.add(new Edge(post, pre));
					} else{
						continue;
					}
				}else{
					//有向网络
					if(pre != post){
						edgeSet.add(new Edge(pre, post));
					}
				}

			}
			reader.close();
			System.out.println("总共"+edgeSet.size()+"行！");
			Iterator<Edge> it = edgeSet.iterator();
			StringBuffer sb = new StringBuffer();
			while(it.hasNext()){
				sb.append(it.next().toString()).append("\r\n");
				if(sb.length() > 1024*1024){
					writer.append(sb.toString());
					sb.delete(0, sb.length());
				}
			}
			writer.append(sb.toString());
			writer.flush();
			writer.close();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void main(String[] args){
/*		EdgeDeweigh ed = new EdgeDeweigh("../data/ips.txt","../data/edge2.txt");
		Edge.netType = ed.netType;
		ed.reduce();
		D.s();*/
	}
	
}

/*********************************************************************************
 *
 * 说明: 表示的一条边的对象
 *
 *********************************************************************************
 */
class Edge{
	//Number Long/Integer
	private Number preNode;
	private Number postNode;
	
	public static NetType netType ;
	
	Edge(Number preNode, Number postNode){
		this.preNode = preNode;
		this.postNode = postNode;
	}
	// GET SET方法
	public Number getPreNode(){
		return this.preNode;
	}
	public void setPreNode(Number preNode){
		this.preNode = preNode;
	}
	public Number getPostNode(){
		return this.postNode;
	}
	public void setPostNode(Number postNode){
		this.postNode = postNode;
	}
	
   @Override  
    public String toString() {  
	   	 return this.preNode + "\t" + this.postNode;
    }  
  
    @Override  
    public int hashCode() {  
        final int prime = 31;  
        int result = 1;  
        result = prime * result + this.preNode.hashCode();  
        result = prime * result + this.postNode.hashCode();  
        return result;  
    }  
  
    @Override  
    public boolean equals(Object obj) {  
        if (this == obj)  
            return true;  
        if (obj == null)  
            return false;  
        if (getClass() != obj.getClass())  
            return false;  
        Edge other = (Edge) obj; 
        //去掉左右端点相同的边
        if (other.preNode == other.postNode)  
            return false; 
        if (!this.preNode.equals(other.preNode))  
            return false;  
        if (!this.postNode.equals(other.postNode))  
            return false; 
       return true; 	
    }
}

